package top.roadvast.springboot.current_time_mills;

import java.util.concurrent.CountDownLatch;

/**
 * @Author 郭泽鹏
 * @Date 2021/10/22 16:52
 * @Version 1.0
 * @Description 测试比较currentTimeMillis方法在单线程和多线程下花费时间的差距
 */
public class CurrentTimeMillsPerDemo {
    private static final int COUNT = 100;

    public static void main(String[] args) throws InterruptedException {
        long beginTime = System.nanoTime();

        for (int i = 0; i < COUNT; i++) {
            System.currentTimeMillis();
        }

        //单线程执行100次耗时
        long elapsedTime = System.nanoTime() - beginTime;
        System.out.println("100 System.current.currentTimeMills() serial calls:" + elapsedTime + "ns");

        // 倒计时计算器
        // 计数从1开始，当减为0时开始执行被await阻塞的线程
        CountDownLatch startLatch = new CountDownLatch(1);
        CountDownLatch endLatch = new CountDownLatch(COUNT);

        //多线程并发执行100次
        for (int i = 0; i < COUNT; i++) {
            new Thread(() -> {
                try{
                    // 使当前线程在锁存器倒计数至零之前一直等待
                    startLatch.await();
                    System.currentTimeMillis();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    // latch减1
                    endLatch.countDown();
                }
            }).start();
        }
        //因为startLatch.await()导致100个线程都堵塞在那里，直到countDown才开始调用系统时间戳方法，模拟并发场景
        beginTime = System.nanoTime();
        startLatch.countDown();
        //直到100个线程调用系统时间戳完毕，再下乡执行统计耗时
        endLatch.await();
        elapsedTime = System.nanoTime() - beginTime;
        System.out.println("100 System.currentTimeMillis() parallel calls:" + elapsedTime + "ns");
    }
}
